#include <iostream>
#include <unistd.h>
#include <sys/wait.h>
#include <vector>
#include <string>
#include <functional>
#include <queue>
#include"task.hpp"

#define DEFAULT_NUM 5

using Func = std::function<void()>;
class Channel
{
public:
    Channel(int wfd, pid_t processid, std::string name) : _wfd(wfd), _processId(processid), _name(name) {}

    ssize_t Write()
    {
        std::string message = _name + " will excute this task ! pid is : " + std::to_string(_processId) ;
        ssize_t n = write(_wfd, message.c_str(), message.size());
        if (n > 0)
        {
            return n;
        }
        else
        {
            std::cout << "write failed!" << std::endl;
            return -1;
        }
    }
    std::string Name() { return _name; }
    int Wfd() { return _wfd; }
    pid_t ProcessId() { return _processId; }

private:
    int _wfd;
    pid_t _processId;
    std::string _name;
    Func _task;
};
class ProcessPool
{
    void CreateChannels(int num)
    {
        for (int i = 0; i < num; i++)
        {
            int pipefd[2];
            int n = pipe(pipefd);
            if (n < 0)
            {
                perror("pipe failed!\n");
                exit(-1);
            }
            int id = fork();
            if (id == 0)
            {
                // 子进程关闭写端，开始进行读取任务
                close(pipefd[1]);
                // dup2(pipefd[0], 0);
                Work(pipefd[0]);
                close(pipefd[0]);
                std::cout<<"hhehehe"<<std::endl;
                exit(-1);
            }
            else
            {
                // 父进程关闭读端，向子进程发送任务
                close(pipefd[0]);
                std::string name = "process " + std::to_string(i) + " ";
                _channels.push_back({pipefd[1], id, name});
            }
        }
    }
    void Work(int fd)
    {
        char buffer[4096];
        while (_isrunning)
        {
            std::cout<<"begin work"<<fd<<std::endl;
            ssize_t n = read(fd, &buffer, sizeof(buffer));
            if (n == 0)
            {
                std::cout << "写端关闭，读取成功" << std::endl;
                break;
            }
            else if (n < 0)
            {
                if (errno == EAGAIN)
                {
                    std::cout << "未读完" << std::endl;
                    continue;
                }
                std::cout << "read failed!" << std::endl;
                break;
            }
            else
            {
                buffer[n] = 0;
                std::cout << buffer << std::endl;
                ExcuteTask(_channels.size()%3);
            }
        }
        std::cout<<"begin end"<<std::endl;

    }
    int Next_Process()
    {
        static int next = 0;
        int ret = next;
        ++next;
        next %= _channels.size();
        return ret;
    }

public:
    void Enqueue(Func cb)
    {
        int next_process = Next_Process();
        Channel ch = _channels[next_process];
        ch.Write();
    }
    ProcessPool(int num = DEFAULT_NUM) : _isrunning(true)
    {
        _channels.reserve(num);
        CreateChannels(num);
    }

private:
    std::vector<Channel> _channels;
    bool _isrunning;
};